home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2004 #11 / Amiga Plus CD - 2004 - No. 11.iso / AmiSoft / Dev / misc / temgen.lha / Temgen / tg-0.11 / generator.c < prev    next >
C/C++ Source or Header  |  2002-12-18  |  26KB  |  1,117 lines

  1. #include "alloc.h"
  2. #include "atom.h"
  3. #include "break.h"
  4. #include "debug.h"
  5. #include "eval.h"
  6. #include "generator.h"
  7. #include "omani.h"  
  8. #include "output.h"
  9. #include "sysdefs.h"
  10. #include "strbuf.h"
  11. #include "use.h"
  12. #include "util.h"  
  13.  
  14. extern struct txttab *text_table;
  15. extern struct lintab *line_table;
  16.  
  17. /* runtime variables */
  18. int  cur_cmd = 0;
  19. int  cur_file = 0;
  20.  
  21.  
  22.  
  23. struct object *new_object( struct object *h, struct object_part *t ) 
  24. {
  25.     struct object *ob;
  26.  
  27.     ob = (struct object*)MALLOC( sizeof(*ob) );
  28.     if ( ob ) {
  29.         ob->h = h;
  30.         ob->t = t;
  31.     }
  32.  
  33.     return ob;
  34. }
  35.  
  36. struct object_part *new_part( const char *name )
  37. {
  38.     struct object_part *p;
  39.  
  40.     p = (struct object_part*)MALLOC( sizeof(*p) );
  41.     if ( p ) {
  42.         p->type = 'n';
  43.         p->val.name = atom( name );
  44.     }
  45.  
  46.     return p;
  47. }
  48.  
  49. struct object_part *new_fun( struct object_part *f, struct explist *l )
  50. {
  51.     struct object_part *p;
  52.  
  53.     p = (struct object_part*)MALLOC( sizeof(*p) );
  54.     if ( p ) {
  55.         p->type = 'f';
  56.         p->val.f.h = f;
  57.         p->val.f.l = l;
  58.     }
  59.  
  60.     return p;
  61. }
  62.  
  63. struct object_part *new_tab( struct object_part *t, struct expression *e )
  64. {
  65.     struct object_part *p;
  66.  
  67.     p = (struct object_part*)MALLOC( sizeof(*p) );
  68.     if ( p ) {
  69.         p->type = 't';
  70.         p->val.t.h = t;
  71.         p->val.t.e = e;
  72.     }
  73.  
  74.     return p;
  75. }
  76.  
  77. struct object_part *new_exppart( struct expression *e )
  78. {
  79.     struct object_part *p;
  80.  
  81.     p = (struct object_part*)MALLOC( sizeof(*p) );
  82.     if ( p ) {
  83.         p->type = 'e';
  84.         p->val.e.e = e;
  85.     }
  86.  
  87.     return p;
  88. }
  89.  
  90. struct explist *new_explist( struct explist *h, struct expression *t )
  91. {
  92.     struct explist *l;
  93.  
  94.     l = (struct explist*)MALLOC( sizeof( *l ) );
  95.     if ( l ) {
  96.         l->h = h;
  97.         l->t = t;
  98.     }
  99.  
  100.     return l;
  101. }
  102.  
  103. struct fldlist *new_fldlist( struct fldlist *h, const char *name,
  104.         struct expression *e )
  105. {
  106.     struct fldlist *l;
  107.  
  108.     l = (struct fldlist*)MALLOC( sizeof( *l ) );
  109.     if ( l ) {
  110.         l->h = h;
  111.         l->name = atom( name );
  112.         l->e = e;
  113.     }
  114.  
  115.     return l;
  116. }
  117.  
  118. struct expression *new_inc( struct expression *e, int inc, int post )
  119. {
  120.     return new_exp( e, (inc== +1)?(post ? 'i': 'I'):(post ? 'd': 'D'), 0 );
  121. }
  122.  
  123. struct expression *new_num( int n )
  124. {
  125.     struct expression *e;
  126.  
  127.     e = (struct expression*)MALLOC( sizeof(*e) );
  128.     if ( e ) {
  129.         e->type = 'i';
  130.         e->val.i = n;
  131.     }
  132.  
  133.     return e;
  134. }
  135.  
  136. struct expression *new_float( float x )
  137. {
  138.     struct expression *e;
  139.  
  140.     e = (struct expression*)MALLOC( sizeof(*e) );
  141.     if ( e ) {
  142.         e->type = 'f';
  143.         e->val.f = x;
  144.     }
  145.  
  146.     return e;
  147. }
  148.  
  149. struct expression *new_string( const char *s )
  150. {
  151.     struct expression *e;
  152.  
  153.     e = (struct expression*)MALLOC( sizeof(*e) );
  154.     if ( e ) {
  155.         e->type = 's';
  156.         e->val.s = STRDUP( unquote(s) );
  157.     }
  158.  
  159.     return e;
  160. }
  161.  
  162. struct expression *new_objexp( struct object *o )
  163. {
  164.     struct expression *e;
  165.  
  166.     e = (struct expression*)MALLOC( sizeof(*e) );
  167.     if ( e ) {
  168.         e->type = 'o';
  169.         e->val.o = o;
  170.     }
  171.  
  172.     return e;
  173. }
  174.  
  175. struct expression *new_array( struct explist *l )
  176. {
  177.     struct expression *e;
  178.  
  179.     e = (struct expression*)MALLOC( sizeof(*e) );
  180.     if ( e ) {
  181.         e->type = 'a';
  182.         e->val.a.reg = nextreg();
  183.         e->val.a.l = l;
  184.     }
  185.  
  186.     return e;
  187. }
  188.  
  189. struct expression *new_record( struct fldlist *l )
  190. {
  191.     struct expression *e;
  192.  
  193.     e = (struct expression*)MALLOC( sizeof(*e) );
  194.     if ( e ) {
  195.         e->type = 'r';
  196.         e->val.r.reg = nextreg();
  197.         e->val.r.l = l;
  198.     }
  199.  
  200.     return e;
  201. }
  202.  
  203. struct expression *new_exp( struct expression *a, char op, 
  204.         struct expression *b )
  205. {
  206.     struct expression *e;
  207.  
  208.     e = (struct expression*)MALLOC( sizeof(*e) );
  209.     if ( e ) {
  210.         e->type = '+';
  211.         e->val.oper.a = a;
  212.         e->val.oper.b = b;
  213.         e->val.oper.op = op;
  214.     }
  215.  
  216.     return e;
  217. }
  218.  
  219. struct command *new_if( struct expression *cond, int else_line, int end_line )
  220. {
  221.     struct command *cmd;
  222.  
  223.     cmd = (struct command*)MALLOC( sizeof(*cmd) );
  224.     if ( cmd ) {
  225.         cmd->type = CMD_IF;
  226.         cmd->cmd.cmd_if.cond = cond;
  227.         cmd->cmd.cmd_if.else_line = else_line;
  228.         cmd->cmd.cmd_if.end_line = end_line;
  229.     }
  230.  
  231.     return cmd;
  232. }
  233.  
  234. struct command *new_goto( int line )
  235. {
  236.     struct command *cmd;
  237.  
  238.     cmd = (struct command*)MALLOC( sizeof(*cmd) );
  239.     if ( cmd ) {
  240.         cmd->type = CMD_GOTO;
  241.         cmd->cmd.cmd_goto.line = line;
  242.     }
  243.  
  244.     return cmd;
  245. }
  246.  
  247. struct param *make_param( struct paramlist *pl )
  248. {
  249.     struct param *p;
  250.     if ( !pl ) return NULL;
  251.  
  252.     p = (struct param*)MALLOC( sizeof(*p) );
  253.     if ( p ) {
  254.         p->t = atom( pl->t );
  255.         if ( pl->t ) FREE( pl->t );
  256.         p->h = make_param( pl->h );
  257.     }
  258.  
  259.     FREE( pl );
  260.     return p;
  261. }
  262.  
  263. struct command *new_function( const char *name, struct paramlist *pl, int end_line )
  264. {
  265.     struct command *cmd;
  266.  
  267.     cmd = (struct command*)MALLOC( sizeof(*cmd) );
  268.     if ( cmd ) {
  269.         cmd->type = CMD_FUNCTION;
  270.         cmd->cmd.cmd_function.name = atom( name );
  271.         cmd->cmd.cmd_function.par = make_param( pl );
  272.         cmd->cmd.cmd_function.end_line = end_line;
  273.     }
  274.  
  275.     return cmd;
  276. }
  277.  
  278. struct paramlist *new_parlist( struct paramlist *pl, const char *param )
  279. {
  280.     struct paramlist *res;
  281.  
  282.     res = (struct paramlist*)MALLOC( sizeof(*res) );
  283.     if ( res ) {
  284.         res->h = pl;
  285.         res->t = STRDUP( param );
  286.     }
  287.  
  288.     return res;
  289. }
  290.  
  291. struct command *new_switch( struct expression *cond, struct caselist *cl,
  292.        int start_line, int end_line )
  293. {
  294.     struct command *cmd;
  295.     int brk;
  296.  
  297.     cmd = (struct command*)MALLOC( sizeof(*cmd) );
  298.     if ( cmd ) {
  299.         cmd->type = CMD_SWITCH;
  300.         cmd->cmd.cmd_switch.cond = cond;
  301.         cmd->cmd.cmd_switch.cl = cl;
  302.         cmd->cmd.cmd_switch.end_line = end_line;
  303.     }
  304.  
  305.     while( 1 ) {
  306.         brk = brk_pop();
  307.         if ( brk <= start_line || brk >= end_line ) {
  308.             if ( brk >= 0 ) brk_push( brk );
  309.             break;
  310.         }
  311.         
  312.         add_cmd( line_table, brk, new_goto( end_line ));
  313.     }
  314.  
  315.     return cmd;
  316. }
  317.  
  318. struct caselist *new_caselist( struct caselist *cl, 
  319.         struct expression *e, int line )
  320. {
  321.     struct caselist *res;
  322.  
  323.     res = (struct caselist*)MALLOC( sizeof(*res) );
  324.     if ( res ) {
  325.         res->h = cl;
  326.         res->e = e;
  327.         res->line = line;
  328.     }
  329.  
  330.     return res;
  331. }
  332.  
  333. struct command *new_for( struct forctl *ctl, int start_line, int end_line )
  334. {
  335.     struct command *cmd;
  336.     int brk;
  337.  
  338.     cmd = (struct command*)MALLOC( sizeof(*cmd) );
  339.     if ( cmd ) {
  340.         cmd->type = CMD_FOR;
  341.         if ( ctl ) {
  342.             cmd->cmd.cmd_for.ctl = *ctl;
  343.             FREE( ctl );
  344.         }
  345.         cmd->cmd.cmd_for.end_line = end_line;
  346.     }
  347.     
  348.     while( 1 ) {
  349.         brk = brk_pop();
  350.         if ( brk <= start_line || brk >= end_line ) {
  351.             if ( brk >= 0 ) brk_push( brk );
  352.             break;
  353.         }
  354.         
  355.         add_cmd( line_table, brk, new_goto( end_line+1 ));
  356.     }
  357.  
  358.     return cmd;
  359. }
  360.  
  361. struct forctl *new_forctl( struct expression *e1,
  362.         struct expression *e2, struct expression *e3 )
  363. {
  364.     static struct expression true;
  365.     struct forctl *ctl;
  366.  
  367.     if ( !e2 ) {
  368.         true.type = 'i';
  369.         true.val.i = 1;
  370.         e2 = &true;
  371.     }
  372.     
  373.     ctl = (struct forctl*)MALLOC( sizeof(*ctl) );
  374.     if ( ctl ) {
  375.         ctl->type = 'c';
  376.         ctl->val.c.e1 = e1;
  377.         ctl->val.c.e2 = e2;
  378.         ctl->val.c.e3 = e3;
  379.     }
  380.  
  381.     return ctl;
  382. }
  383.  
  384. struct forctl *new_lforctl( struct expression *i, struct expression *obj )
  385. {
  386.     struct forctl *ctl;
  387.  
  388.     ctl = (struct forctl*)MALLOC( sizeof(*ctl) );
  389.     if ( ctl ) {
  390.         ctl->type = 'l';
  391.         ctl->val.l.i = i;
  392.         ctl->val.l.obj = obj;
  393.     }
  394.  
  395.     return ctl;
  396. }
  397.  
  398. struct command *new_return( struct expression *e )
  399. {
  400.     struct command *cmd;
  401.  
  402.     cmd = (struct command*)MALLOC( sizeof(*cmd) );
  403.     if ( cmd ) {
  404.         cmd->type = CMD_RETURN;
  405.         cmd->cmd.cmd_exp.e = e;
  406.     }
  407.  
  408.     return cmd;
  409. }
  410.  
  411. struct command *new_embed( struct expression *e )
  412. {
  413.     struct command *cmd;
  414.  
  415.     cmd = (struct command*)MALLOC( sizeof(*cmd) );
  416.     if ( cmd ) {
  417.         cmd->type = CMD_EMBED;
  418.         cmd->cmd.cmd_exp.e = e;
  419.     }
  420.  
  421.     return cmd;
  422. }
  423.  
  424. struct command *new_emit( struct expression *e )
  425. {
  426.     struct command *cmd;
  427.  
  428.     cmd = (struct command*)MALLOC( sizeof(*cmd) );
  429.     if ( cmd ) {
  430.         cmd->type = CMD_EMIT;
  431.         cmd->cmd.cmd_exp.e = e;
  432.     }
  433.  
  434.     return cmd;
  435. }
  436.  
  437. struct command *new_exit( struct expression *e )
  438. {
  439.     struct command *cmd;
  440.  
  441.     cmd = (struct command*)MALLOC( sizeof(*cmd) );
  442.     if ( cmd ) {
  443.         cmd->type = CMD_EXIT;
  444.         cmd->cmd.cmd_exp.e = e;
  445.     }
  446.  
  447.     return cmd;
  448. }
  449.  
  450. struct command *new_output( struct expression *e )
  451. {
  452.     struct command *cmd;
  453.  
  454.     cmd = (struct command*)MALLOC( sizeof(*cmd) );
  455.     if ( cmd ) {
  456.         cmd->type = CMD_OUTPUT;
  457.         cmd->cmd.cmd_exp.e = e;
  458.     }
  459.  
  460.     return cmd;
  461. }
  462.  
  463. struct command *new_local( const char *name )
  464. {
  465.     struct command *cmd;
  466.  
  467.     cmd = (struct command*)MALLOC( sizeof(*cmd) );
  468.     if ( cmd ) {
  469.         cmd->type = CMD_LOCAL;
  470.         cmd->cmd.cmd_local.name = atom( name );
  471.     }
  472.  
  473.     return cmd;
  474. }
  475.  
  476. struct command *new_use( const char *name )
  477. {
  478.     struct command *cmd;
  479.  
  480.     cmd = (struct command*)MALLOC( sizeof(*cmd) );
  481.     if ( cmd ) {
  482.         cmd->type = CMD_USE;
  483.         do_use( cmd->cmd.cmd_use.name = atom( name ) );
  484.     }
  485.  
  486.     return cmd;
  487. }
  488.  
  489. struct command *new_break( int line )
  490. {
  491.     struct command *cmd;
  492.  
  493.     cmd = (struct command*)MALLOC( sizeof(*cmd) );
  494.     if ( cmd ) {
  495.         cmd->type = CMD_BREAK;
  496.     }
  497.     
  498.     brk_push( line );
  499.     
  500.     return cmd;
  501. }
  502.  
  503. struct command *new_push( void )
  504. {
  505.     struct command *cmd;
  506.  
  507.     cmd = (struct command*)MALLOC( sizeof(*cmd) );
  508.     if ( cmd ) {
  509.         cmd->type = CMD_PUSH;
  510.     }
  511.     
  512.     return cmd;
  513. }
  514.  
  515. struct command *new_pop( void )
  516. {
  517.     struct command *cmd;
  518.  
  519.     cmd = (struct command*)MALLOC( sizeof(*cmd) );
  520.     if ( cmd ) {
  521.         cmd->type = CMD_POP; 
  522.     }
  523.     
  524.     return cmd;
  525. }
  526.  
  527. struct command *new_cmdexp( struct expression *e )
  528. {
  529.     struct command *cmd;
  530.  
  531.     cmd = (struct command*)MALLOC( sizeof(*cmd) );
  532.     if ( cmd ) {
  533.         cmd->type = CMD_EXP;
  534.         cmd->cmd.cmd_exp.e = e;
  535.     }
  536.  
  537.     return cmd;
  538. }
  539.  
  540. int lcmd_add_c( struct command *cmd, int start, int end )
  541. {
  542.     int n;
  543.  
  544.     n = cmd->cmd.cmd_data.count;
  545.  
  546.     if ( cmd->cmd.cmd_data.size <= n ) {
  547.         struct dataitem *old;
  548.         old = cmd->cmd.cmd_data.tab; 
  549.         cmd->cmd.cmd_data.size += 4;           /* TODO tune it ! */
  550.         cmd->cmd.cmd_data.tab = (struct dataitem*)REALLOC( old, 
  551.                 cmd->cmd.cmd_data.size * sizeof(cmd->cmd.cmd_data.tab[0]));
  552.         if ( !cmd->cmd.cmd_data.tab ) {
  553.             cmd->cmd.cmd_data.tab = old;
  554.             cmd->cmd.cmd_data.size -= 4;
  555.             return -1;
  556.         }
  557.     }
  558.  
  559.     cmd->cmd.cmd_data.count++;
  560.     cmd->cmd.cmd_data.tab[ n ].start = start;
  561.     cmd->cmd.cmd_data.tab[ n ].end = end;
  562.     cmd->cmd.cmd_data.tab[ n ].exp = NULL;
  563.     return 0;
  564. }
  565.  
  566. struct command *build_lcmd_c( struct command *cmd, int start, int end )
  567. {
  568.     int n;
  569.  
  570.     if ( !cmd ) cmd = (struct command*)CALLOC( 1, sizeof(*cmd) );
  571.     if ( cmd ) {
  572.         cmd->type = CMD_DATA;
  573.         n = cmd->cmd.cmd_data.count; 
  574.  
  575.         if ( n == 0 && start!=0 ) {
  576.             /* add empty slot starting from begin of line */
  577.             if ( lcmd_add_c( cmd, 0, 1 ) ) return NULL;
  578.             n = cmd->cmd.cmd_data.count;
  579.         }
  580.  
  581.         if ( n ) {  
  582.             if ( cmd->cmd.cmd_data.tab[ n-1 ].exp == 0 )
  583.                 cmd->cmd.cmd_data.tab[ n-1 ].end = end;
  584.             else {
  585.                 if ( start > cmd->cmd.cmd_data.tab[ n-1 ].end )
  586.                     start = cmd->cmd.cmd_data.tab[ n-1 ].end;   
  587.                 lcmd_add_c( cmd, start, end );
  588.             }
  589.         } else 
  590.             lcmd_add_c( cmd, start, end );
  591.     }
  592.  
  593.     return cmd;
  594. }
  595.  
  596. int lcmd_add_e( struct command *cmd, struct expression *e,
  597.         int start, int end )
  598. {
  599.     int n;
  600.  
  601.     n = cmd->cmd.cmd_data.count;
  602.     if ( cmd->cmd.cmd_data.size <= n ) {
  603.         struct dataitem *old;
  604.         old = cmd->cmd.cmd_data.tab; 
  605.         cmd->cmd.cmd_data.size += 4;           /* TODO tune it ! */
  606.         cmd->cmd.cmd_data.tab = (struct dataitem*)REALLOC( old, 
  607.                 cmd->cmd.cmd_data.size * sizeof(cmd->cmd.cmd_data.tab[0]));
  608.         if ( !cmd->cmd.cmd_data.tab ) {
  609.             cmd->cmd.cmd_data.tab = old;
  610.             cmd->cmd.cmd_data.size -= 4;
  611.             return -1;
  612.         }
  613.     }
  614.  
  615.     cmd->cmd.cmd_data.count++;
  616.     cmd->cmd.cmd_data.tab[ n ].start = start;
  617.     cmd->cmd.cmd_data.tab[ n ].end = end;
  618.     cmd->cmd.cmd_data.tab[ n ].exp = e;
  619.     return 0;
  620. }
  621.  
  622. struct command *build_lcmd_e( struct command *cmd, struct expression *e,
  623.         int start, int end )
  624. {
  625.     if ( !cmd ) cmd = (struct command*)CALLOC( 1, sizeof(*cmd) );
  626.     if ( cmd ) {
  627.         int n = cmd->cmd.cmd_data.count;
  628.  
  629.         if ( n == 0 ) { 
  630.             if ( start!=0 ) {
  631.                 /* add empty slot starting from begin of line */
  632.                 if ( lcmd_add_c( cmd, 0, start )) return NULL;
  633.             }
  634.         }
  635.         else {
  636.             if ( cmd->cmd.cmd_data.tab[ n-1 ].exp ) {
  637.                 /* add cmd_c between the two expressions */
  638.                 if ( cmd->cmd.cmd_data.tab[ n-1 ].end != start )
  639.                     if ( lcmd_add_c( cmd, cmd->cmd.cmd_data.tab[ n-1 ].end,
  640.                                 start )) return NULL;
  641.             }
  642.             else {
  643.                 /* enlarge previous cmd_c if needed */
  644.                 cmd->cmd.cmd_data.tab[ n-1 ].end = start;
  645.             }
  646.         }
  647.  
  648.         cmd->type = CMD_DATA;
  649.         lcmd_add_e( cmd, e, start, end );
  650.     }
  651.  
  652.     return cmd;
  653. }
  654.  
  655. void close_line( int line, int end )
  656. {
  657.     int n;
  658.     struct command *cmd;
  659.  
  660.     cmd = (struct command*)lt_get( line_table, line );
  661.     if ( cmd && cmd->type == CMD_DATA ) {
  662.         struct dataitem *it;
  663.  
  664.         if ( (n = cmd->cmd.cmd_data.count) > 0 ) {
  665.             it = cmd->cmd.cmd_data.tab + n-1;   
  666.             if ( it->exp && it->end != end ) 
  667.                 lcmd_add_c( cmd, it->end, end );
  668.             else 
  669.                 it->end = end;
  670.         }
  671.     }
  672. }
  673.  
  674. int  run_data_cmd( struct command *c, const char *line )
  675. {
  676.     int i;
  677.     static struct strbuf *buf = NULL;
  678.     static int buflock = 0;
  679.    
  680.     if ( !( c && line ) ) return 0;
  681.     
  682.     if ( !buflock ) {
  683.         if ( buf )
  684.             sb_clear( buf );
  685.         else
  686.             buf = new_strbuf( 512, 512 );
  687.     }
  688.  
  689.     if ( !buf ) return -1;
  690.     buflock++;
  691.  
  692.     for ( i=0; i<c->cmd.cmd_data.count; i++ )  {
  693.         struct dataitem *it;
  694.  
  695.         it = c->cmd.cmd_data.tab + i;
  696.         if ( it->exp == 0 ) {
  697.             sb_cat( (buflock!=1) ? NULL: buf, 
  698.                     unescape(line + it->start, it->end - it->start),
  699.                     it->end - it->start);
  700.         } else  
  701.             sb_cat( (buflock!=1) ? NULL: buf, 
  702.                     evalstr(it->exp), 0x7ffffff0 );
  703.     }
  704.  
  705.     buflock--;
  706.     if ( !buflock ) writeout( sb_data(buf) );
  707.     return 0;
  708. }
  709.  
  710. int run_if( struct command *c, int start_line, struct sourcefile *sf )
  711. {
  712.     int A, obj;
  713.     
  714.     A = tmp_alloc();
  715.     obj = eval( A, c->cmd.cmd_if.cond );
  716.     obj = istrue( obj );
  717.     tmp_free( A );
  718.     if ( obj ) 
  719.         return start_line + 1;
  720.     else 
  721.         return c->cmd.cmd_if.else_line + 1;
  722. }
  723.  
  724. int run_switch( struct command *c, struct sourcefile *sf )
  725. {
  726.     int obj, A;
  727.     int line;
  728.    
  729.     A = tmp_alloc();
  730.     obj = eval( A, c->cmd.cmd_switch.cond );
  731.     line = find_case( obj, c->cmd.cmd_switch.cl );
  732.     tmp_free( A );
  733.     return (line >= 0) ? line: c->cmd.cmd_switch.end_line;
  734. }
  735.  
  736. int run_for( struct command *c, int start_line, struct sourcefile *sf )
  737. {
  738.     int sel, i, obj, index, n;
  739.     
  740.     switch( c->cmd.cmd_for.ctl.type ) {
  741.         case 'c':
  742.             /* this is the classic C 'for' command instance */
  743.             for( eval( 0, c->cmd.cmd_for.ctl.val.c.e1 ); 
  744.                     istrue( eval( 0, c->cmd.cmd_for.ctl.val.c.e2 ) );
  745.                     eval( 0, c->cmd.cmd_for.ctl.val.c.e3 )) {
  746.  
  747.                 index = start_line+1;
  748.  
  749.                 while( 1 ) {
  750.                     struct command *cmd;
  751.                     cmd = lt_get( sf->lt, index );
  752.                     index = run_cmd( index, cmd, sf );
  753.  
  754.                     if ( index < start_line ||
  755.                             index >= c->cmd.cmd_for.end_line ) 
  756.                         break;
  757.                 }
  758.                     
  759.                 if ( index > c->cmd.cmd_for.end_line ) /* @break */
  760.                     break;
  761.             }
  762.             break;
  763.         case 'l':
  764.             obj = select_obj( c->cmd.cmd_for.ctl.val.l.obj );
  765.             sel = select_obj( c->cmd.cmd_for.ctl.val.l.i ); 
  766.             n = ob_count( obj );
  767.             
  768.             for ( i=0; i<n; i++ ) {
  769.                 int name = ob_fieldname( obj, i );
  770.                 if ( name <= 0 ) break;
  771.                 ob_set( sel, 's', atom_name(name) );
  772.                 
  773.                 index = start_line+1;
  774.  
  775.                 while( 1 ) {
  776.                     struct command *cmd;
  777.                     cmd = lt_get( sf->lt, index );
  778.                     index = run_cmd( index, cmd, sf );
  779.  
  780.                     if ( index < start_line ||
  781.                             index >= c->cmd.cmd_for.end_line ) 
  782.                         break;
  783.                 }
  784.                 
  785.                 if ( index > c->cmd.cmd_for.end_line ) /* @break */
  786.                     break;
  787.             }
  788.             break;
  789.     }
  790.     
  791.     return 0;
  792. }
  793.  
  794. static void do_exit( struct expression *e )
  795. {
  796.     int a, typ;
  797.     const char *s;
  798.     int n;
  799.     double x;
  800.     
  801.     if ( !e ) exit( 0 );
  802.     a = tmp_alloc();
  803.     eval( a, e );
  804.     typ = ob_type( a );
  805.     switch( typ ) {
  806.         case 'i':
  807.             exit( ob_geti(a) );
  808.         case 'f':
  809.             exit( ob_getf(a) );
  810.             break;
  811.         case 's':
  812.             s = ob_gets(a);
  813.             x = strtod( s, NULL );
  814.             n = atoi( s );
  815.             if ( n == x )
  816.                 exit( n );
  817.             else
  818.                 exit( x );
  819.             break;
  820.         default:
  821.             exit( 0 );
  822.     }
  823. }
  824.  
  825. int run_cmd( int index, struct command *c, struct sourcefile *sf )
  826. {
  827.     const char *line;
  828.     if ( !c ) return index+1;
  829.     
  830.     cur_cmd = index;
  831.     cur_file = sf ? sf->fname: 0;
  832.     
  833.     if ( debugger ) deb_cmd( index, c, sf );
  834.  
  835.     switch( c->type ) {
  836.         case CMD_EMBED:
  837.             line = evalstr( c->cmd.cmd_exp.e );
  838.             embed( atom(line) );
  839.             return index + 1;
  840.         case CMD_EMIT:
  841.             line = evalstr( c->cmd.cmd_exp.e );
  842.             setemb( atom(line) );
  843.             return index + 1;
  844.         case CMD_OUTPUT:
  845.             line = evalstr( c->cmd.cmd_exp.e );
  846.             setout( atom(line), 0 );
  847.             return index + 1;
  848.         case CMD_EXP:
  849.             eval( 0, c->cmd.cmd_exp.e );
  850.             return index + 1;
  851.         case CMD_FUNCTION:
  852.             return c->cmd.cmd_function.end_line + 1;
  853.         case CMD_IF:
  854.             return run_if( c, index, sf );
  855.         case CMD_SWITCH:
  856.             return run_switch( c, sf );
  857.         case CMD_FOR:
  858.             if ( run_for( c, index, sf ) ) fatal( "fatal error in loop" );
  859.             return c->cmd.cmd_for.end_line + 1;
  860.         case CMD_DATA:
  861.             line = tt_find( sf->tt, index );
  862.             if ( run_data_cmd( c, line ) ) fatal( "fatal error generating data" );
  863.             return index + 1;
  864.         case CMD_GOTO:
  865.             return c->cmd.cmd_goto.line;
  866.         case CMD_PUSH:
  867.             push_out();
  868.             return index + 1;
  869.         case CMD_POP: 
  870.             pop_out();
  871.             return index + 1;
  872.         case CMD_RETURN:
  873.             setret( c->cmd.cmd_exp.e );
  874.             return -1;
  875.         case CMD_LOCAL:
  876.             create_local( c->cmd.cmd_local.name );
  877.             return index + 1;
  878.         case CMD_EXIT:
  879.             do_exit( c->cmd.cmd_exp.e );
  880.         default:
  881.             return index + 1;
  882.     }
  883. }
  884.  
  885. void add_cmd( struct lintab *lt, int line, struct command *c )
  886. {
  887.     struct command *next;
  888.     lt_set( lt, line, c );
  889.     if ( c ) switch( c->type ) {
  890.         case CMD_IF:
  891.             next = new_goto( c->cmd.cmd_if.end_line + 1 );
  892.             add_cmd( lt, c->cmd.cmd_if.else_line, next );
  893.             break;
  894.         case CMD_FUNCTION:
  895.             next = new_return( NULL );
  896.             add_cmd( lt, c->cmd.cmd_function.end_line, next );
  897.             break;
  898.     } 
  899. }
  900.  
  901.  
  902. #include <stdio.h>
  903.  
  904. void dump_explist( char *buf, int size, struct explist* );
  905.  
  906. void dump_part( char *buf, int size, struct object_part *p )
  907. {
  908.     int len;
  909.     
  910.     if ( !p ) {
  911.         snprintf( buf, size, "[NULL]" );
  912.         return;
  913.     }
  914.  
  915.     switch( p->type ) {
  916.         case 'n':
  917.             snprintf( buf, size, atom_name( p->val.name ) );
  918.             break;
  919.         case 'f':
  920.             dump_part( buf, size, p->val.f.h );
  921.             len = strlen( buf );
  922.             if ( len > size-6 ) break;
  923.             strcat( buf, "( " );
  924.             dump_explist( buf+len+2, size-len-2, p->val.f.l );
  925.             len = strlen( buf );
  926.             if ( len > size-3 ) break;
  927.             strcat( buf, " )" );
  928.             break;
  929.         case 't':
  930.             dump_part( buf, size, p->val.t.h );
  931.             len = strlen( buf );
  932.             if ( len > size-6 ) break;
  933.             strcat( buf, "[ " );
  934.             dump_expression( buf+len+2, size-len-2, p->val.t.e );
  935.             len = strlen( buf );
  936.             if ( len > size-3 ) break;
  937.             strcat( buf, " ]" );
  938.             break;
  939.         default:
  940.             snprintf( buf, size, "[%c:?]", p->type );
  941.     }
  942. }
  943.  
  944. void dump_obj( char *buf, int size, struct object *o )
  945. {
  946.     int len;
  947.     
  948.     if ( !o ) {
  949.         snprintf( buf, size, "<NULL>" );
  950.         return;
  951.     }
  952.  
  953.     if ( o->h ) {
  954.         dump_obj( buf, size, o->h );
  955.         len = strlen( buf );
  956.         if ( len > size-3 ) return;
  957.         strcat( buf, "." );
  958.     }
  959.     else len = -1;
  960.  
  961.     dump_part( buf+len+1, size-len-1, o->t );
  962. }
  963.  
  964. void dump_expression( char *buf, int size, struct expression *e )
  965. {
  966.     int len;
  967.     
  968.     if ( !e ) {
  969.         snprintf( buf, size, "(NULL expression)" );
  970.         return;
  971.     }
  972.  
  973.     switch( e->type ) {
  974.         case 'i':
  975.             snprintf( buf, size, "%d", e->val.i );
  976.             break;
  977.         case 'f':
  978.             snprintf( buf, size, "%f", e->val.f );
  979.             break;
  980.         case 's':
  981.             snprintf( buf, size, "%s", e->val.s );
  982.             break;
  983.         case 'o':
  984.             dump_obj( buf, size, e->val.o );
  985.             break;
  986.         case '+':
  987.             snprintf( buf, size, "(" );
  988.             dump_expression( buf+1, size-1, e->val.oper.a );
  989.             len = strlen( buf );
  990.             if ( len < size-8 ) {
  991.                 snprintf( buf+len, size-len, " %c ", e->val.oper.op );
  992.                 dump_expression( buf+len+3, size-len-3, e->val.oper.b );
  993.                 len = strlen( buf );
  994.                 if ( len < size-2 )
  995.                     snprintf( buf + len, size-len, ")" );
  996.             }
  997.     }
  998. }
  999.  
  1000. void dump_explist( char *buf, int size, struct explist *l )
  1001. {
  1002.     int len;
  1003.     
  1004.     if ( !l ) {
  1005.         snprintf( buf, size, "(NULL)" );
  1006.         return;
  1007.     }
  1008.  
  1009.     if ( l->h ) {
  1010.         dump_explist( buf, size, l->h );
  1011.         len = strlen( buf );
  1012.         if ( len > size-4 ) return;
  1013.         strcat( buf, ", " );
  1014.     }
  1015.     else len = -2;
  1016.  
  1017.     dump_expression( buf+len+2, size-len-2, l->t );
  1018. }
  1019.  
  1020. void dump_param( struct param *p )
  1021. {
  1022.     if ( p ) {
  1023.         dump_param( p->h );
  1024.         if ( p->h ) printf( ", " );
  1025.         printf( "%s", atom_name( p->t ));
  1026.     }
  1027. }
  1028.  
  1029.  
  1030. #if 0 
  1031.  
  1032. void dump_caselist( struct caselist *cl )
  1033. {
  1034.     if ( !cl ) return;
  1035.     dump_caselist( cl->h );
  1036.     printf( "%d:@  case ", cl->line );
  1037.     dump_expression( cl->e );
  1038.     printf( " :\n" );
  1039. }
  1040.  
  1041. void dump_cmd( int line, struct command *c )
  1042. {
  1043.     if ( !c ) {
  1044.         printf( "(Null)\n" );
  1045.         return;
  1046.     }
  1047.  
  1048.     switch( c->type ) {
  1049.         case      CMD_IF:         
  1050.             printf( "@if " );
  1051.             dump_expression( c->cmd.cmd_if.cond );
  1052.             printf( "\nelse: line %d\ngoto: line %d\n", c->cmd.cmd_if.else_line,
  1053.                     c->cmd.cmd_if.end_line  );
  1054.             printf( "%d:@endif", c->cmd.cmd_if.end_line );
  1055.             printf( "\n" );
  1056.             break;
  1057.         case      CMD_FUNCTION:  
  1058.             printf( "@function %s(", atom_name(c->cmd.cmd_function.name) );
  1059.             dump_param( c->cmd.cmd_function.par );
  1060.             printf( ")\n" );
  1061.             printf( "%d:@endfunction\n", c->cmd.cmd_function.end_line );
  1062.             break;
  1063.         case      CMD_SWITCH:   
  1064.             printf( "@switch " );
  1065.             dump_expression( c->cmd.cmd_switch.cond );
  1066.             printf( "\n" );
  1067.             dump_caselist( c->cmd.cmd_switch.cl );
  1068.             printf( "%d:@endswitch", c->cmd.cmd_switch.end_line );
  1069.             printf( "\n" );
  1070.             break;
  1071.         case      CMD_FOR:     
  1072.             printf( "@for ( " );
  1073.             dump_expression( c->cmd.cmd_for.e1 ); printf( "; " );
  1074.             dump_expression( c->cmd.cmd_for.e2 ); printf( "; " );
  1075.             dump_expression( c->cmd.cmd_for.e3 ); 
  1076.             printf( " )\n" );
  1077.             printf( "%d:@endfor", c->cmd.cmd_for.end_line );
  1078.             printf( "\n" );
  1079.             break;
  1080.         case      CMD_RETURN: 
  1081.             printf( "@return " );
  1082.             dump_expression( c->cmd.cmd_return.e );
  1083.             printf( "\n" );
  1084.             break;
  1085.         case      CMD_BREAK: 
  1086.             printf( "@break" );
  1087.             printf( "\n" );
  1088.             break;
  1089.         case      CMD_EXP:  
  1090.             printf( "@exp:" );
  1091.             dump_expression( c->cmd.cmd_exp.e );
  1092.             printf( "\n" );
  1093.             break;
  1094.         case      CMD_DATA:
  1095.             printf( "%s", tt_find( text_table, line ));
  1096.             break;
  1097.     }
  1098. }
  1099. #endif
  1100.  
  1101. void warning( const char *msg )
  1102. {
  1103.         const char *fname;
  1104.         fname = atom_name( cur_file );
  1105.         if ( fname && fname[0] )
  1106.                 fprintf( stderr, "%s:%d: %s\n", fname, cur_cmd, msg );
  1107.         else
  1108.                 fprintf( stderr, "tg: %s\n", msg );
  1109. }
  1110.  
  1111. void fatal( const char *msg )
  1112. {
  1113.         warning( msg );
  1114.         exit( 1 );
  1115. }
  1116.  
  1117.